﻿using System;
using Runtime.Services.Battle.Entity;
using UnityEngine;
using UnityEngine.Assertions;

namespace Runtime.Services.Battle {

    public partial interface IDFR_BattleServiceBase {

        IDFR_BattleLocalPositionProvider GetLocalPositionProvider(DFR_BattleEntityInstanceID instanceID);

        IDFR_BattleWorldPositionProvider GetWorldPositionProvider(DFR_BattleEntityInstanceID instanceID);
    }

    /// <summary>
    /// 战斗地图位置提供者
    /// </summary>
    public interface IDFR_BattleMapPositionProvider {

        /// <summary>
        /// 是否可用
        /// </summary>
        bool IsEnabled { get; }

        /// <summary>
        /// 地图位置
        /// </summary>
        DFR_BattleMapPosition MapPosition { get; }

        /// <summary>
        /// 上一帧地图位置
        /// </summary>
        DFR_BattleMapPosition LastMapPosition { get; }

        /// <summary>
        /// 移动速度
        /// </summary>
        F64 MoveSpeed { get; }

        /// <summary>
        /// 显示偏移
        /// </summary>
        Vector2F64 RenderOffset { get; }

        /// <summary>
        /// 预测移动
        /// </summary>
        /// <param name="seconds">需要预测的时间(秒)</param>
        DFR_BattleMapPosition SupposeMove(F64 seconds);

        /// <summary>
        /// 销毁
        /// </summary>
        void Dispose();
    }

    /// <summary>
    /// 战斗位置提供者
    /// </summary>
    public interface IDFR_BattleLocalPositionProvider {

        /// <summary>
        /// 位置
        /// </summary>
        Vector3 LocalPosition { get; }

        /// <summary>
        /// 销毁
        /// </summary>
        void Dispose();
    }

    /// <summary>
    /// 战斗世界位置提供者
    /// </summary>
    public interface IDFR_BattleWorldPositionProvider {

        /// <summary>
        /// 世界位置
        /// </summary>
        Vector3 WorldPosition { get; }

        /// <summary>
        /// 销毁
        /// </summary>
        void Dispose();
    }

    public abstract partial class DFR_BattleServiceBase<TRecord> {

        private sealed class LocalPositionProvider : IDFR_BattleLocalPositionProvider {

            private Transform m_Target;

            public LocalPositionProvider(Transform target) {
                m_Target = target;
            }

            private Vector3 m_LastLocalPosition;
            public Vector3 LocalPosition {
                get {
                    if (m_Target != null) {
                        m_LastLocalPosition = m_Target.localPosition;
                    }
                    return m_LastLocalPosition;
                }
            }

            public void Dispose() {
                m_Target = null;
            }
        }

        private sealed class WorldPositionProvider : IDFR_BattleWorldPositionProvider {

            private Transform m_Target;

            public WorldPositionProvider(Transform target) {
                m_Target = target;
            }

            private Vector3 m_LastWorldPosition;
            public Vector3 WorldPosition {
                get {
                    if (m_Target != null) {
                        m_LastWorldPosition = m_Target.position;
                    }
                    return m_LastWorldPosition;
                }
            }

            public void Dispose() {
                m_Target = null;
            }
        }

        public IDFR_BattleLocalPositionProvider GetLocalPositionProvider(DFR_BattleEntityInstanceID instanceID) {
            Assert.IsTrue(m_EntityRecordDictionary.ContainsKey(instanceID));
            var record = m_EntityRecordDictionary[instanceID];
            return new LocalPositionProvider(record.Container.transform);
        }

        public IDFR_BattleWorldPositionProvider GetWorldPositionProvider(DFR_BattleEntityInstanceID instanceID) {
            Assert.IsTrue(m_EntityRecordDictionary.ContainsKey(instanceID));
            var record = m_EntityRecordDictionary[instanceID];
            return new WorldPositionProvider(record.Container.transform);
        }
    }
}
